home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 March / EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso / earcd / misc / pdflib / p_filter.c < prev    next >
C/C++ Source or Header  |  1999-01-01  |  4KB  |  168 lines

  1. /* p_filter.c
  2.  * Copyright (C) 1997-98 Thomas Merz. All rights reserved.
  3.  *
  4.  * ASCII85 and Hex encoding for PDFlib 
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <fcntl.h>
  9.  
  10. #include "p_intern.h"
  11.  
  12. #ifdef DOS
  13. #include <io.h>
  14. #include <stdlib.h>
  15. #endif
  16.  
  17. static const unsigned long power85[5] = 
  18.     { 1L, 85L, 85L*85, 85L*85*85, 85L*85*85*85};
  19.  
  20. /* Auxiliary routines */
  21.  
  22. /* output one ASCII byte and keep track of characters per line */
  23. static void 
  24. pdf_outbyte(PDF *p, byte c)
  25. {
  26.     if (fputc(c, p->fp) == EOF)
  27.     pdf_error(p, PDF_FATAL, "Write error in pdf_outbyte()");
  28.  
  29. #define MAX_CHARS_PER_LINE    64
  30.     /* insert line feed */
  31.     if (++(p->chars_on_this_line) == MAX_CHARS_PER_LINE)
  32.     {
  33.     fputc('\n', p->fp);
  34.     p->chars_on_this_line = 0;
  35.     }
  36. }
  37.  
  38. void
  39. pdf_ASCII85Encode(PDF *p, PDF_data_source *src)
  40. {
  41.     unsigned long word, v;
  42.     int i, fetched;
  43.     byte buf[4];
  44.  
  45.     src->init(p, src);
  46.     if (!src->fill(p, src)) {
  47.     pdf_error(p, PDF_WARN, "Data underrun in pdf_ASCII85Encode");
  48.     fputs("~>\n", p->fp);            /* EOD marker */
  49.     return;
  50.     }
  51.  
  52.     p->chars_on_this_line = 0;
  53.  
  54.     while (1)
  55.     {
  56.     for (fetched = 0; fetched < 4; fetched++)
  57.     {
  58.         if (src->bytes_available == 0 && !src->fill(p, src))
  59.         break;
  60.         buf[fetched] = *(src->next_byte);
  61.         src->next_byte++;
  62.         src->bytes_available--;
  63.     }
  64.     if (fetched < 4)
  65.         break;
  66.  
  67.     /* 4 bytes available ==> output 5 bytes */
  68.     word = ((unsigned long)(((unsigned int)buf[0] << 8) + buf[1]) << 16) +
  69.            (((unsigned int)buf[2] << 8) + buf[3]);
  70.     if (word == 0)
  71.         pdf_outbyte(p, (byte) 'z');       /* shortcut for 0 */
  72.     else
  73.     {
  74.         /* calculate 5 ASCII85 bytes and output them */
  75.         for (i = 4; i >= 0; i--) {
  76.         v = word / power85[i];
  77.         pdf_outbyte(p, (byte)v + '!');
  78.         word -= v * power85[i];
  79.         }
  80.     }
  81.     }
  82.  
  83.     word = 0;
  84.  
  85.     /* 0-3 bytes left */
  86.     if (fetched != 0)
  87.     {
  88.     for (i = fetched - 1; i >= 0; i--)   /* accumulate bytes */
  89.         word += (unsigned long)buf[i] << 8 * (3-i);
  90.  
  91.     /* encoding as above, but output only fetched+1 bytes */
  92.     for (i = 4; i >= 4-fetched; i--)
  93.     {
  94.         v = word / power85[i];
  95.         pdf_outbyte(p, (byte)v + '!');
  96.         word -= v * power85[i];
  97.     }
  98.     }
  99.  
  100.     src->terminate(p, src);
  101.  
  102.     fputs("~>\n", p->fp);            /* EOD marker */
  103. }
  104.  
  105. void 
  106. pdf_ASCIIHexEncode(PDF *p, PDF_data_source *src)
  107. {
  108.     static const char BinToHex[] = "0123456789ABCDEF";
  109.     int CharsPerLine;
  110.     long i;
  111.     byte *data;
  112.  
  113.     CharsPerLine = 0;
  114.  
  115.     src->init(p, src);
  116.  
  117.     while (src->fill(p, src))
  118.     {
  119.     
  120.     for (data=src->next_byte, i=src->bytes_available; i > 0; i--, data++)
  121.     {
  122.       putc(BinToHex[*data>>4], p->fp);           /* first nibble  */
  123.       putc(BinToHex[*data & 0x0F], p->fp);       /* second nibble */
  124.       if ((CharsPerLine += 2) >= 64) {
  125.         putc('\n', p->fp);
  126.         CharsPerLine = 0;
  127.       }
  128.     }
  129.     }
  130.  
  131.     src->terminate(p, src);
  132.     (void) fputs(">\n", p->fp);         /* EOD marker for PDF hex strings */
  133. }
  134.  
  135. /* methods for constructing a data source from a memory buffer */
  136.  
  137. /* dummy for use in PDF_data_source */
  138. static void
  139. pdf_noop(PDF *p, PDF_data_source *src)
  140. {
  141. }
  142.  
  143. static bool
  144. pdf_data_source_buf_fill(PDF *p, PDF_data_source *src)
  145. {
  146.     if (src->next_byte == NULL) {
  147.     src->next_byte        = src->buffer_start;
  148.     src->bytes_available    = src->buffer_length;
  149.     return true;
  150.     }
  151.  
  152.     return false;
  153. }
  154.  
  155. void
  156. PDF_data_source_from_buf(PDF *p, PDF_data_source *src, byte *buffer, long len)
  157. {
  158.     src->init        = pdf_noop;
  159.     src->fill        = pdf_data_source_buf_fill;
  160.     src->terminate    = pdf_noop;
  161.  
  162.     src->buffer_start    = buffer;
  163.     src->buffer_length    = len;
  164.  
  165.     src->bytes_available= 0;
  166.     src->next_byte    = NULL;
  167. }
  168.